In dieser Lerneinheit schauen wir uns die Java Database Connectivity an und wie man damit über eine Java-Anwendung in eine MariaDB-Datenbank hineinschreiben und etwas auslesen kann. Die Java Database Connectivity ist eine Datenbankschnittstelle der Java-Plattform, die eine einheitliche Schnittstelle zu Datenbanken verschiedener Hersteller bietet und speziell auf relationale Datenbanken ausgerichtet ist. Java Database Connectivity ist in seiner Funktion als universelle Datenbankschnittstelle vergleichbar mit ODBC unter Windows oder DBI unter Perl. Für jede spezifische Datenbank sind eigene Treiber erforderlich, welche die Java Database Connectivity-Spezifikation implementieren. Diese Treiber werden meist vom Hersteller des Datenbanksystems geliefert. Zu den Aufgaben von Java Database Connectivity gehört es, Datenbankverbindungen aufzubauen und sie zu verwalten, SQL-Anfragen an die Datenbank weiterzuleiten und die Ergebnisse in eine für Java nutzbare Form umzuwandeln und dem Programm zur Verfügung zu stellen. Diese Folie zeigt die möglichen Arten, wie eine Java-Anwendung über Java Database Connectivity mit einer Datenbank verbunden werden kann. Im Zentrum steht dabei die Java Database Connectivity-API, also die standardisierte Schnittstelle, die es Java-Programmen erlaubt, SQL-Befehle auszuführen und mit relationalen Datenbanken zu kommunizieren. Damit dieser Zugriff funktioniert, wird ein sogenannter Java Database Connectivity-Treiber benötigt, der die Anfragen aus der Java-Welt in die spezifische Sprache der jeweiligen Datenbank übersetzt. Dabei gibt es vier grundsätzliche Arten von Java Database Connectivity-Treibern, die sich in ihrem Aufbau und ihrer Funktionsweise unterscheiden: Typ-1-Treiber werden als Java Database Connectivity-ODBC-Bridge bezeichnet. Sie übersetzen Java Database Connectivity-Aufrufe in ODBC-Aufrufe, also in ein älteres plattformabhängiges Datenbankschnittstellenprotokoll. Damit können Java-Anwendungen indirekt auf jede Datenbank zugreifen, für die ein ODBC-Treiber vorhanden ist. Diese Lösung ist jedoch veraltet und wird nicht mehr empfohlen, da sie plattformabhängig und vergleichsweise langsam ist. Typ-2-Treiber sind sogenannte native API-Treiber. Sie übersetzen Java Database Connectivity-Aufrufe direkt in die proprietäre Programmierschnittstelle der Datenbank, verwenden dazu aber native Bibliotheken, die auf dem jeweiligen Betriebssystem installiert sein müssen. Diese Lösung ist schneller als Typ 1, erfordert aber eine plattformspezifische Konfiguration und Installation der nativen Komponenten. Typ-3-Treiber sind Netzwerkprotokoll-Treiber. Sie senden die Java Database Connectivity-Aufrufe über ein Netzwerkprotokoll an einen Middleware-Server, der diese dann an die eigentliche Datenbank weiterleitet. Diese Architektur ermöglicht eine hohe Flexibilität und zentrale Steuerung, bringt aber zusätzliche Komplexität durch die notwendige Middleware mit sich. Typ-4-Treiber schließlich sind sogenannte reine Java-Treiber. Sie übersetzen Java Database Connectivity-Aufrufe direkt in das Datenbankprotokoll und kommunizieren ohne Umwege direkt mit der Datenbank. Diese Treiber benötigen keine nativen Bibliotheken und sind vollständig in Java geschrieben. Sie gelten als die modernste und am häufigsten eingesetzte Lösung, da sie plattformunabhängig, effizient und wartungsarm sind. Durch diese verschiedenen Treiberarchitekturen ist Java Database Connectivity in der Lage, auf eine Vielzahl unterschiedlicher Datenbanksysteme zuzugreifen – und zwar auf eine einheitliche und für den Java-Programmierer transparente Weise. Das macht Java Database Connectivity zu einem zentralen Werkzeug für datenbankgestützte Java-Anwendungen. Bevor wir mit der Datenbank arbeiten können, müssen wir in der Entwicklungsumgebung Eclipse ein neues Java-Projekt anlegen. Dies ist der erste technische Schritt, um Java Database Connectivity überhaupt einsetzen zu können. Ohne ein passendes Projekt können wir später keinen Code schreiben oder Bibliotheken einbinden. Um mit der Datenbank arbeiten zu können, brauchen wir den sogenannten Java Database Connectivity Connector. Das ist meist eine JAR-Datei – also ein Java-Archiv –, das wir aus einer ZIP-Datei entpacken müssen. Diese Datei enthält den Code, den Java braucht, um mit der Datenbank zu sprechen. Die entpackte JAR-Datei wird in den Ressourcen-Ordner unseres Projekts verschoben. Anschließend müssen wir die Datei über das Build-Menü mit dem Projekt verknüpfen. Das geht mit einem Rechtsklick auf die Datei und dann über den Menüpunkt „Add to Build Path“. Erst wenn dieser Schritt abgeschlossen ist, erkennt Eclipse die Java Database Connectivity Bibliothek. Auch hier geht es noch einmal darum, sicherzustellen, dass der Java Database Connectivity Connector korrekt eingebunden ist. Das ist Voraussetzung dafür, dass unsere späteren Zugriffe auf die Datenbank funktionieren. Ohne diesen Schritt würde unser Java-Programm die entsprechenden Klassen und Methoden nicht kennen. In dieser Folie wird gezeigt, wie der erste lesende Zugriff über Java Database Connectivity vorbereitet wird. Dazu wurde bereits im Vorfeld eine relationale Datenbank mit mehreren Tabellen in phpMyAdmin erstellt – einem webbasierten Verwaltungswerkzeug für MariaDB-Datenbanken. Die Datenbank enthält beispielhafte Einträge, auf die später mit einem Java-Programm zugegriffen werden soll. Ziel ist es, diese Daten über eine SQL-Abfrage mit Java Database Connectivity aus Java heraus auszulesen. Die Folie stellt die Struktur der Datenbank grafisch dar, sodass ersichtlich ist, mit welchen Tabellen und Spalten die Anwendung arbeiten wird. Diese Folie zeigt eine Detailansicht der Inhalte der Datenbank, wie sie in phpMyAdmin dargestellt werden. Hier sind konkrete Datensätze sichtbar, die später vom Java-Programm über Java Database Connectivity ausgelesen werden sollen. Es handelt sich dabei beispielsweise um Kunden-, Produkt- oder Bestelldaten, die in Tabellenform gespeichert sind. Die Darstellung unterstreicht, dass die Daten bereits vollständig vorliegen und der Fokus nun auf dem Zugriff über Java liegt. Nun wird gezeigt, wie der Zugriff technisch über Java Database Connectivity in Java erfolgt. Im gezeigten Java-Code wird zunächst eine Verbindung zur Datenbank aufgebaut. Dazu wird eine URL mit den Zugangsdaten übergeben, einschließlich Datenbankname, Benutzername und Passwort. Nach erfolgreicher Verbindung wird ein Statement-Objekt erzeugt, über das SQL-Abfragen an die Datenbank geschickt werden können. Anschließend erfolgt die Ausführung eines SELECT-Befehls. Die Ergebnisse dieser Abfrage werden in einem ResultSet gespeichert. Dieses wird in einer Schleife durchlaufen, wobei jeder Datensatz einzeln ausgelesen und weiterverarbeitet werden kann – zum Beispiel durch die Ausgabe in der Konsole. Die Folie vermittelt damit die komplette Kette eines lesenden Datenbankzugriffs: von der Verbindung über die Anfrage bis zur Verarbeitung der Ergebnisse. Bei der gesamten Datenbank-Kommunikation kann einiges schief laufen. Es kann fehlerhafte Abfragen geben, der Datenbank-Server kann abgeschaltet sein oder die Netzwerkverbindung zum Datenbank-Server kann gestört sein. In diesem ersten Beispiel ist schon einmal eine Fehlerbehandlung rund um den Datenbankzugriff mit "try"-"catch" skizziert. Momentan werden nur SQL-Fehler abgefangen, also fehlerhafte SQL-Befehle. Das könnte man noch ausbauen. Außerdem wäre noch ein finally-Block sehr wichtig! Jede Connection, die man öffnet, sollte man in jedem Fall auch schließen. Dies gilt auch für ein Statement und für ein ResultSet. Dafür gibt es jeweils einen close-Befehl. Generell schließt man offene Verbindungen genau anders herum, wie man sie öffnet. Also zuerst schließt man das ResultSet, dann das Statement und dann die Connection. Da bei jedem Schließen auch wieder eine Exception geworfen werden kann, sollte jedes Close seinerseits nochmal mit einem "Try" und einem "Catch Exception e" geschlossen werden. In den weiteren Code-Beispielen wird auf die komplette Fehlerbehandlung verzichtet. Sie würde von dem Kern der Datenbankzugriffe ablenken, die ich ja hier zeigen will. Die Fehlerbehandlung würde die Anzahl der Codezeilen fast verdoppeln. Eine robuste Fehlerbehandlung ist in der Praxis natürlich unverzichtbar! In dieser Folie geht es um das Schreiben von Daten in die Datenbank über Java Database Connectivity. Die Struktur ist ähnlich wie beim lesenden Zugriff, allerdings wird nun ein "INSERT INTO"-Befehl verwendet. Damit wird ein neuer Datensatz in eine bestehende Tabelle eingefügt. Wichtig ist hier die korrekte Einbindung von Benutzereingaben, um Sicherheitslücken wie SQL-Injection zu vermeiden. Externe Eingaben dürfen niemals direkt in SQL-Befehle eingebettet werden. Stattdessen muss man auf Prepared Statements zurückgreifen, die eine sichere und strukturierte Übergabe von Parametern ermöglichen. Sie stellen sicher, dass Benutzereingaben nicht als SQL-Code interpretiert werden. Diese Folie zeigt die Kontrolle des vorangegangenen Schreibvorgangs in der Datenbankverwaltung. Nach dem Ausführen des Insert-Befehls über Java wird in phpMyAdmin überprüft, ob der neue Datensatz tatsächlich eingefügt wurde. Die erfolgreiche Eintragung bestätigt, dass der schreibende Zugriff über Java Database Connectivity korrekt funktioniert hat. Auf diese Art und Weise können nicht nur Insert-, sondern auch Update- und Delete-Befehle umgesetzt werden. Diese drei Befehle sind die zentralen Werkzeuge für schreibende und verändernde Zugriffe in relationalen Datenbanken. Der gezeigte Test über phpMyAdmin dient dabei als einfache Möglichkeit, die Ergebnisse eines Java-Datenbankzugriffs visuell zu überprüfen.